package org.example.demo.controller;

import org.example.demo.model.CommonResponse;
import org.example.demo.model.bo.EducationCertificationIssueCertificateInputBO;
import org.example.demo.model.bo.EducationCertificationGetCertificateInputBO;
import org.example.demo.model.bo.EducationCertificationRevokeCertificateInputBO;
import org.example.demo.model.bo.EducationCertificationUpdateCertificateInputBO;
import org.example.demo.model.bo.EducationCertificationVerifyCertificateInputBO;
import org.example.demo.model.bo.EducationCertificationCertificatesInputBO;
import org.example.demo.service.EducationCertificationService;
import org.example.demo.service.StudentStorageService;
import org.fisco.bcos.sdk.transaction.model.dto.CallResponse;
import org.fisco.bcos.sdk.transaction.model.dto.TransactionResponse;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Arrays;
import java.util.ArrayList;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Calendar;

@RestController
@RequestMapping("/api")
public class CertificateController {
    @Resource
    private Map<String, EducationCertificationService> serviceMap;

    @Resource
    private StudentStorageService studentStorageService;

    /**
     * 处理区块链返回值，去掉方括号和额外空格
     */
    private String cleanBlockchainResponse(String response) {
        if (response == null) {
            return "";
        }
        
        // 去除方括号
        String cleaned = response;
        if (cleaned.startsWith("[") && cleaned.endsWith("]")) {
            cleaned = cleaned.substring(1, cleaned.length() - 1);
        }
        
        // 去除额外空格
        return cleaned.trim();
    }

    /**
     * 更安全地解析区块链返回的证书数据
     * 处理返回值中可能包含逗号的情况
     */
    private String[] parseCertificateData(String rawData) {
        if (rawData == null || rawData.isEmpty()) {
            return new String[0];
        }
        
        // 先清理格式
        String cleaned = cleanBlockchainResponse(rawData);
        
        // 解析字段，预期至少有5个字段
        List<String> result = new ArrayList<>();
        
        // 简单的逗号分割可能不足以处理复杂数据
        // 这里我们假设字段不包含复杂的嵌套结构
        String[] parts = cleaned.split(",");
        
        // 处理前4个字段和最后一个字段
        if (parts.length >= 5) {
            // 假设前4个字段是字符串值，最后一个是布尔值
            // 证书类型
            result.add(parts[0].trim());
            
            // 证书编号
            result.add(parts[1].trim());
            
            // 颁发日期
            result.add(parts[2].trim());
            
            // 如果中间部分存在多余的逗号（比如在机构名称中），将它们合并
            StringBuilder institutionBuilder = new StringBuilder();
            for (int i = 3; i < parts.length - 1; i++) {
                if (i > 3) {
                    institutionBuilder.append(",");
                }
                institutionBuilder.append(parts[i].trim());
            }
            result.add(institutionBuilder.toString());
            
            // 有效状态（最后一个字段）
            result.add(parts[parts.length - 1].trim());
        }
        
        return result.toArray(new String[0]);
    }

    @GetMapping("/certificates")
    public CommonResponse<List<Map<String, Object>>> listCertificates(
            @RequestParam(value = "limit", required = false, defaultValue = "100") int limit,
            @RequestParam(value = "offset", required = false, defaultValue = "0") int offset) {
        try {
            List<Map<String, Object>> allCertificates = new ArrayList<>();
            
            // 直接从区块链上获取所有证书，不依赖本地存储
            if (serviceMap != null && !serviceMap.isEmpty()) {
                String serviceKey = serviceMap.keySet().iterator().next();
                EducationCertificationService service = serviceMap.get(serviceKey);
                
                System.out.println("仅从区块链获取所有证书数据...");
                System.out.println("使用合约地址: " + service.getAddress());
                System.out.println("请求参数 - limit: " + limit + ", offset: " + offset);
                
                try {
                    // 确保交易处理器已初始化
                    if (service.getTxProcessor() == null) {
                        System.err.println("交易处理器未初始化");
                        return CommonResponse.error("Transaction processor not initialized");
                    }
                    
                    // 获取所有颁发证书的事件日志，这样可以更快地定位有效证书
                    System.out.println("尝试获取证书颁发事件...");
                    
                    // 获取下一个证书ID，即总数量
                    BigInteger nextId = BigInteger.ONE; // 默认从1开始
                    try {
                        CallResponse nextIdResponse = service.nextCertificateId();
                        if (nextIdResponse == null || nextIdResponse.getValues() == null) {
                            System.err.println("获取下一个证书ID返回null或空值");
                            return CommonResponse.error("Failed to get next certificate ID");
                        }
                        
                        String nextIdStr = cleanBlockchainResponse(nextIdResponse.getValues());
                        
                        // 如果还有逗号分隔的多个值，只取第一个
                        if (nextIdStr.contains(",")) {
                            nextIdStr = nextIdStr.split(",")[0].trim();
                        }
                        
                        // 处理可能的括号
                        nextIdStr = nextIdStr.replaceAll("[()]", "").trim();
                        
                        // 转换为BigInteger
                        if (nextIdStr.isEmpty()) {
                            System.err.println("获取下一个证书ID返回空字符串");
                            nextIdStr = "1"; // 默认为1
                        }
                    
                        System.out.println("处理后的nextCertificateId值: " + nextIdStr);
                        nextId = new BigInteger(nextIdStr);
                        System.out.println("链上下一个证书ID: " + nextId);
                    } catch (Exception e) {
                        System.err.println("获取下一个证书ID异常: " + e.getMessage());
                        // 使用默认值继续
                    }
                    
                    // 获取证书数据
                    if (nextId.compareTo(BigInteger.ONE) > 0) {
                        System.out.println("检测到链上证书ID最大为: " + nextId.subtract(BigInteger.ONE));
                        
                        // 计算起始位置和实际获取的最大数量
                        BigInteger startId = BigInteger.ONE;
                        if (offset > 0) {
                            startId = BigInteger.valueOf(offset + 1);
                        }
                        
                        // 最大不能超过总数量
                        BigInteger maxId = nextId;
                        if (limit > 0) {
                            BigInteger endId = startId.add(BigInteger.valueOf(limit));
                            if (endId.compareTo(nextId) > 0) {
                                endId = nextId;
                            }
                            maxId = endId;
                        }
                        
                        System.out.println("获取证书数据 (ID范围: " + startId + " 到 " + maxId.subtract(BigInteger.ONE) + ")");
                        
                        for (BigInteger i = startId; i.compareTo(maxId) < 0; i = i.add(BigInteger.ONE)) {
                            try {
                                System.out.println("获取证书ID=" + i);
                                EducationCertificationGetCertificateInputBO testInput = 
                                    new EducationCertificationGetCertificateInputBO(i);
                                CallResponse testResponse = service.getCertificate(testInput);
                                
                                if (testResponse != null) {
                                    String originalResult = testResponse.getValues();
                                    String cleanedResult = cleanBlockchainResponse(originalResult);
                                    System.out.println("证书ID=" + i + ", 原始返回值: " + originalResult);
                                    System.out.println("证书ID=" + i + ", 处理后: " + cleanedResult);
                                    
                                    // 尝试解析返回值
                                    String[] fields = parseCertificateData(cleanedResult);
                                    if (fields.length >= 5) {
                                        // 证书有效，构建证书对象
                                        Map<String, Object> certificate = new HashMap<>();
                                        certificate.put("id", i.toString());
                                        certificate.put("certificateId", i.toString());
                                        certificate.put("certificateType", fields[0]);
                                        certificate.put("certificateNumber", fields[1]);
                                        
                                        // 格式化日期显示
                                        String issueDate = fields[2];
                                        try {
                                            // 尝试解析日期格式 - 如果是时间戳，转为标准日期
                                            if (issueDate.matches("\\d+")) {
                                                long timestamp = Long.parseLong(issueDate);
                                                // 判断是秒还是毫秒级时间戳
                                                if (timestamp < 10000000000L) { // 秒级时间戳
                                                    timestamp *= 1000;
                                                }
                                                Date date = new Date(timestamp);
                                                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                                                issueDate = sdf.format(date);
                                            }
                                        } catch (Exception e) {
                                            // 如果解析失败，保留原始格式
                                            System.err.println("日期解析失败: " + e.getMessage());
                                        }
                                        
                                        certificate.put("timestamp", issueDate);
                                        certificate.put("institution", fields[3]);
                                        certificate.put("isValid", Boolean.parseBoolean(fields[4]));
                                        
                                        // 获取证书对应的学生地址 - 使用区块链原始数据
                                        try {
                                            // 获取证书对应的学生地址 - 使用区块链原始数据
                                            CallResponse rawResponse = service.certificates(new EducationCertificationCertificatesInputBO(i));
                                            
                                            if (rawResponse != null && rawResponse.getValues() != null) {
                                                String rawResult = rawResponse.getValues();
                                                System.out.println("\n证书 " + i + " 的完整原始数据: " + rawResult);
                                                
                                                // 解析原始数据中的学生地址 - 通常是第二个字段
                                                String[] rawFields = rawResult.replace("[", "").replace("]", "").split(",");
                                                for (int idx = 0; idx < Math.min(8, rawFields.length); idx++) {
                                                    System.out.println("字段 " + idx + ": [" + rawFields[idx] + "]");
                                                }
                                                
                                                if (rawFields.length > 1) {
                                                    String studentAddress = rawFields[1].trim();
                                                    System.out.println("提取学生地址: " + studentAddress);
                                                    
                                                    // 不进行ID转换，直接使用原始地址
                                                    certificate.put("studentId", studentAddress);
                                                    certificate.put("studentAddress", studentAddress);
                                                } else {
                                                    certificate.put("studentId", "链上证书#" + i);
                                                    certificate.put("studentAddress", "证书ID:" + i);
                                                }
                                            } else {
                                                certificate.put("studentId", "链上证书#" + i);
                                                certificate.put("studentAddress", "证书ID:" + i);
                                            }
                                        } catch (Exception e) {
                                            System.err.println("获取证书 " + i + " 原始数据失败: " + e.getMessage());
                                            certificate.put("studentId", "链上证书#" + i);
                                            certificate.put("studentAddress", "证书ID:" + i);
                                        }
                                        
                                        certificate.put("blockNumber", 0);
                                        certificate.put("txHash", "");
                                        certificate.put("blockHash", "");
                                        certificate.put("status", "confirmed");
                                        
                                        // 生成证书哈希
                                        String hexString = i.toString(16);
                                        StringBuilder paddedHex = new StringBuilder(hexString);
                                        while (paddedHex.length() < 64) {
                                            paddedHex.insert(0, '0');
                                        }
                                        certificate.put("certificateHash", "0x" + paddedHex.toString());
                                        
                                        // 添加到结果列表
                                        allCertificates.add(certificate);
                                        System.out.println("成功添加证书ID=" + i + "到结果列表");
                                    } else {
                                        System.err.println("证书ID=" + i + "的数据格式不正确，字段数: " + fields.length);
                                    }
                                } else {
                                    System.err.println("获取证书ID=" + i + "返回null");
                                }
                            } catch (Exception e) {
                                System.err.println("获取证书ID=" + i + "失败: " + e.getMessage());
                            }
                        }
                    }
                } catch (Exception e) {
                    System.err.println("获取链上证书总数失败: " + e.getMessage());
                }
            } else {
                System.err.println("区块链服务不可用，无法获取证书数据");
                return CommonResponse.error("Blockchain service not available");
            }
            
            System.out.println("从区块链获取所有证书数据完成，共" + allCertificates.size() + "条");
            
            if (allCertificates.isEmpty()) {
                System.out.println("未从链上检索到任何有效证书，请确认链上是否存在证书数据");
                System.out.println("如果之前颁发过证书，请检查颁发操作是否成功提交到区块链");
            }
            
            return CommonResponse.ok(allCertificates);
        } catch (Exception e) {
            System.err.println("获取证书列表失败: " + e.getMessage());
            e.printStackTrace();
            return CommonResponse.error(e.getMessage());
        }
    }

    @PostMapping("/certificates")
    public CommonResponse<Map<String, Object>> issueCertificate(@RequestBody Map<String, String> certificateData) {
        try {
            // 1. 验证必要参数
            String studentAddress = certificateData.get("studentAddress");
            String certificateType = certificateData.get("certificateType");
            String certificateNumber = certificateData.get("certificateNumber");
            String issueDate = certificateData.get("issueDate");
            String institution = certificateData.get("institution");
            String hash = certificateData.get("hash");
            String studentId = certificateData.get("studentId");

            System.out.println("收到证书颁发请求：" + certificateData);

            if (studentAddress == null || certificateType == null || certificateNumber == null || institution == null) {
                return CommonResponse.error("缺少必要参数");
            }

            // 处理日期格式，确保使用有效的日期格式
            if (issueDate == null || issueDate.isEmpty()) {
                // 如果未提供颁发日期，使用当前日期
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                issueDate = sdf.format(new Date());
            }

            // 如果缺少哈希，生成一个简单哈希
            if (hash == null || hash.isEmpty()) {
                String dataToHash = certificateType + certificateNumber + issueDate + institution;
                byte[] generatedHash = generateSimpleHash(dataToHash);
                hash = "0x" + org.fisco.bcos.sdk.utils.Numeric.toHexString(generatedHash).substring(2);
            }

            // 2. 创建证书输入对象
            EducationCertificationIssueCertificateInputBO inputBO = new EducationCertificationIssueCertificateInputBO();
            inputBO.set_studentId(studentAddress);
            inputBO.set_certificateType(certificateType);
            inputBO.set_certificateNumber(certificateNumber);
            inputBO.set_issueDate(issueDate);
            inputBO.set_institution(institution);
            
            try {
            // 将16进制字符串转换为bytes32
                byte[] hashBytes = org.fisco.bcos.sdk.utils.Numeric.hexStringToByteArray(hash);
            inputBO.set_hash(hashBytes);
            } catch (Exception e) {
                System.err.println("证书哈希转换错误: " + e.getMessage());
                e.printStackTrace();
                return CommonResponse.error("Invalid certificate hash: " + e.getMessage());
            }

            // 3. 调用区块链服务颁发证书
            System.out.println("准备调用区块链服务颁发证书: " + inputBO);
            System.out.println("studentAddress: " + studentAddress);
            System.out.println("certificateType: " + certificateType);
            System.out.println("certificateNumber: " + certificateNumber);
            System.out.println("issueDate: " + issueDate);
            System.out.println("institution: " + institution);
            System.out.println("hash: " + hash);
            
            try {
                if (serviceMap == null) {
                    System.err.println("serviceMap为空");
                    return CommonResponse.error("Service map is null");
                }
                
                if (serviceMap.isEmpty()) {
                    System.err.println("serviceMap为空映射");
                    return CommonResponse.error("No blockchain service instances available");
                }
                
                // 获取第一个可用的服务实例
                String serviceKey = serviceMap.keySet().iterator().next();
                EducationCertificationService service = serviceMap.get(serviceKey);
                System.out.println("使用服务实例 key: " + serviceKey);
                
                if (service == null) {
                    System.err.println("无法获取区块链服务实例");
                    return CommonResponse.error("Blockchain service not available");
                }
                
                System.out.println("区块链服务地址: " + service.getAddress());
                
                // 3.1 检查学生记录是否存在，如果不存在则创建
                try {
                    // 尝试获取学生记录
                    org.example.demo.model.bo.EducationCertificationGetStudentRecordInputBO studentRecordInput = 
                        new org.example.demo.model.bo.EducationCertificationGetStudentRecordInputBO();
                    studentRecordInput.set_studentId(studentAddress);
                    
                    System.out.println("检查学生记录是否存在: " + studentAddress);
                    service.getStudentRecord(studentRecordInput);
                    
                    System.out.println("学生记录已存在，可以继续颁发证书");
                } catch (Exception e) {
                    // 如果学生记录不存在，则创建
                    System.out.println("学生记录不存在，准备创建学生记录: " + e.getMessage());
                    
                    String studentName = studentId != null ? "学生" + studentId : "新学生";
                    
                    org.example.demo.model.bo.EducationCertificationCreateStudentRecordInputBO createStudentInput = 
                        new org.example.demo.model.bo.EducationCertificationCreateStudentRecordInputBO();
                    createStudentInput.setStudentId(studentAddress);
                    createStudentInput.setName(studentName); // 使用studentId或默认姓名
                    createStudentInput.setEducation(certificateType); // 使用证书类型作为学历
                    
                    // 使用当前年份作为毕业年份
                    Calendar now = Calendar.getInstance();
                    createStudentInput.setGraduationYear(java.math.BigInteger.valueOf(now.get(Calendar.YEAR)));
                    
                    System.out.println("创建学生记录: " + createStudentInput);
                    TransactionResponse createStudentResponse = service.createStudentRecord(createStudentInput);
                    
                    if (createStudentResponse == null || createStudentResponse.getTransactionReceipt() == null 
                            || !createStudentResponse.getTransactionReceipt().isStatusOK()) {
                        System.err.println("创建学生记录失败");
                        if (createStudentResponse != null && createStudentResponse.getTransactionReceipt() != null) {
                            System.err.println("错误信息: " + createStudentResponse.getTransactionReceipt().getMessage());
                        }
                        return CommonResponse.error("Failed to create student record before issuing certificate");
                    }
                    
                    System.out.println("学生记录创建成功，继续颁发证书");
                }
                
                // 3.2 颁发证书
                TransactionResponse response = service.issueCertificate(inputBO);
            
            // 4. 检查交易回执
                if (response == null) {
                    System.err.println("交易响应为null");
                    return CommonResponse.error("Transaction response is null");
                }
                
                if (response.getTransactionReceipt() == null) {
                    System.err.println("交易回执为null");
                    return CommonResponse.error("Transaction receipt is null");
                }
                
                // 记录详细的区块链交易信息
                System.out.println("==== 区块链交易信息 ====");
                System.out.println("交易哈希: " + response.getTransactionReceipt().getTransactionHash());
                System.out.println("区块号: " + response.getTransactionReceipt().getBlockNumber());
                System.out.println("区块哈希: " + response.getTransactionReceipt().getBlockHash());
                System.out.println("Gas使用量: " + response.getTransactionReceipt().getGasUsed());
                System.out.println("交易状态: " + response.getTransactionReceipt().getStatus());
                System.out.println("证书哈希: " + hash);
                System.out.println("======================");
                
                System.out.println("交易回执状态: " + response.getTransactionReceipt().getStatus());
                System.out.println("交易回执消息: " + response.getTransactionReceipt().getMessage());
                
            if (!response.getTransactionReceipt().isStatusOK()) {
                    System.err.println("交易执行失败: " + response.getTransactionReceipt().getMessage());
                return CommonResponse.error("Failed to issue certificate on blockchain: " + 
                    response.getTransactionReceipt().getMessage());
            }

            // 5. 创建完整的证书信息
            Map<String, Object> certificate = new HashMap<>();
                String txHash = response.getTransactionReceipt().getTransactionHash();
                BigInteger certificateId = new BigInteger("0");
                
                try {
                    // 获取当前最新的证书ID
                    CallResponse nextIdResponse = service.nextCertificateId();
                    if (nextIdResponse != null && nextIdResponse.getValues() != null) {
                        String nextIdStr = cleanBlockchainResponse(nextIdResponse.getValues());
                        
                        // 如果还有逗号分隔的多个值，只取第一个
                        if (nextIdStr.contains(",")) {
                            nextIdStr = nextIdStr.split(",")[0].trim();
                        }
                        
                        BigInteger nextId = new BigInteger(nextIdStr);
                        // 颁发的证书ID应该是nextId-1
                        certificateId = nextId.subtract(BigInteger.ONE);
                        System.out.println("新颁发证书ID: " + certificateId);
                    } else {
                        System.err.println("获取下一个证书ID失败，返回null或空值");
                    }
                } catch (Exception e) {
                    System.err.println("获取证书ID失败: " + e.getMessage());
                }
                
                certificate.put("id", certificateId.toString()); // 使用证书ID作为唯一标识
                certificate.put("certificateId", certificateId.toString());
                certificate.put("txHash", txHash);
            certificate.put("blockNumber", response.getTransactionReceipt().getBlockNumber());
                certificate.put("blockHash", response.getTransactionReceipt().getBlockHash());
                certificate.put("gasUsed", response.getTransactionReceipt().getGasUsed());
                certificate.put("transactionIndex", response.getTransactionReceipt().getTransactionIndex());
            certificate.put("studentId", certificateData.get("studentId")); // 原始学生ID
            certificate.put("studentAddress", studentAddress);
            certificate.put("certificateType", certificateType);
            certificate.put("certificateNumber", certificateNumber);
                certificate.put("timestamp", issueDate);
            certificate.put("institution", institution);
                certificate.put("certificateHash", hash);
            certificate.put("status", "confirmed");
            certificate.put("isValid", true);

            // 6. 保存证书信息到本地存储
                try {
                    // 不再将证书保存到本地存储，而是完全依赖区块链
                    System.out.println("证书已成功上链，不再保存到本地存储");
                } catch (Exception e) {
                    System.err.println("证书处理异常: " + e.getMessage());
                    e.printStackTrace();
                }

            return CommonResponse.ok(certificate);
            } catch (Exception e) {
                System.err.println("颁发证书过程中发生异常: " + e.getClass().getName() + ": " + e.getMessage());
                if (e.getCause() != null) {
                    System.err.println("异常原因: " + e.getCause().getMessage());
                }
                e.printStackTrace();
                return CommonResponse.error("Failed to issue certificate: " + e.getMessage());
            }
        } catch (Exception e) {
            System.err.println("证书颁发失败: " + e.getMessage());
            e.printStackTrace(); // 添加详细错误日志
            return CommonResponse.error("Failed to issue certificate: " + e.getMessage());
        }
    }

    @GetMapping("/certificates/{certificateId}")
    public CommonResponse<Object> getCertificate(@PathVariable String certificateId) {
        try {
            if (serviceMap == null || serviceMap.isEmpty()) {
                return CommonResponse.error("Blockchain service not available");
            }
            
            // 获取第一个可用的服务实例
            String serviceKey = serviceMap.keySet().iterator().next();
            EducationCertificationService service = serviceMap.get(serviceKey);
            
            EducationCertificationGetCertificateInputBO inputBO = new EducationCertificationGetCertificateInputBO();
            inputBO = new EducationCertificationGetCertificateInputBO(new BigInteger(certificateId));
            return CommonResponse.ok(service.getCertificate(inputBO));
        } catch (Exception e) {
            return CommonResponse.error(e.getMessage());
        }
    }

    @DeleteMapping("/certificates/{certificateId}")
    public CommonResponse<Void> revokeCertificate(
            @PathVariable String certificateId,
            @RequestBody(required = false) Map<String, Object> requestData) {
        try {
            System.out.println("\n============= 开始撤销证书 =============");
            System.out.println("收到撤销证书请求，证书ID: " + certificateId);
            
            if (certificateId == null || certificateId.isEmpty()) {
                System.err.println("证书ID为空");
                return CommonResponse.error("Certificate ID cannot be empty");
            }
            
            // 检查服务可用性
            if (serviceMap == null || serviceMap.isEmpty()) {
                System.err.println("区块链服务不可用");
                return CommonResponse.error("Blockchain service not available");
            }
            
            // 获取请求参数
            String contractAddress = requestData != null ? (String) requestData.get("contractAddress") : null;
            System.out.println("请求中的合约地址: " + (contractAddress != null ? contractAddress : "未提供"));
            
            // 获取第一个可用的服务实例
            String serviceKey = serviceMap.keySet().iterator().next();
            EducationCertificationService service = serviceMap.get(serviceKey);
            
            if (service == null) {
                System.err.println("未找到合约服务实例");
                return CommonResponse.error("Blockchain service instance not available");
            }
            
            System.out.println("合约地址: " + service.getAddress());
            System.out.println("使用服务实例: " + serviceKey);
            
            try {
                // 验证证书ID能否转换为BigInteger
                BigInteger certId;
                try {
                    certId = new BigInteger(certificateId);
                    System.out.println("证书ID转换为BigInteger成功: " + certId);
                } catch (NumberFormatException e) {
                    System.err.println("证书ID格式错误，无法转换为数字: " + e.getMessage());
                    return CommonResponse.error("Invalid certificate ID format: " + e.getMessage());
                }
                
                // 最简化的调用方式：只传递证书ID
                EducationCertificationRevokeCertificateInputBO inputBO = 
                    new EducationCertificationRevokeCertificateInputBO();
                inputBO.set_certificateId(certId);
                
                System.out.println("创建撤销证书输入参数: " + inputBO);
                
                // 直接调用智能合约撤销证书
                System.out.println("调用智能合约撤销证书...");
                TransactionResponse response = service.revokeCertificate(inputBO);
                
                if (response == null) {
                    System.err.println("撤销证书交易响应为空");
                    return CommonResponse.error("Revocation transaction response is null");
                }
                
                if (response.getTransactionReceipt() == null) {
                    System.err.println("撤销证书交易回执为空");
                    return CommonResponse.error("Revocation transaction receipt is null");
                }
                
                System.out.println("撤销证书交易已发送，交易哈希: " + 
                    response.getTransactionReceipt().getTransactionHash());
                
                // 检查交易状态
                if (!response.getTransactionReceipt().isStatusOK()) {
                    System.err.println("撤销证书交易执行失败: " + response.getTransactionReceipt().getMessage());
                    return CommonResponse.error("Failed to revoke certificate on blockchain: " + 
                        response.getTransactionReceipt().getMessage());
                }
                
                // 更新本地存储中的证书状态
                try {
                    studentStorageService.updateCertificateStatus(certificateId, false);
                    System.out.println("本地证书状态已更新为无效");
                } catch (Exception e) {
                    System.err.println("更新本地证书状态失败，但区块链交易已成功: " + e.getMessage());
                    // 不影响主流程，继续返回成功
                }
                
                System.out.println("证书撤销成功，ID: " + certificateId);
                System.out.println("============= 撤销证书完成 =============\n");
                return CommonResponse.ok();
            } catch (Exception e) {
                System.err.println("撤销证书过程中出错: " + e.getMessage());
                e.printStackTrace();
                return CommonResponse.error("Failed to revoke certificate: " + e.getMessage());
            }
        } catch (Exception e) {
            System.err.println("撤销证书请求处理失败: " + e.getMessage());
            e.printStackTrace();
            return CommonResponse.error("Failed to process certificate revocation: " + e.getMessage());
        }
    }

    @PutMapping("/certificates/{certificateId}")
    public CommonResponse<Map<String, Object>> updateCertificate(
            @PathVariable String certificateId,
            @RequestBody Map<String, Object> certificateData) {
        try {
            System.out.println("更新证书请求 - 证书ID: " + certificateId);
            System.out.println("证书数据: " + certificateData);
            
            // 检查参数
            if (certificateData == null || certificateData.isEmpty()) {
                return CommonResponse.error("证书数据不能为空");
            }
            
            // 必需字段检查
            String certificateType = String.valueOf(certificateData.getOrDefault("certificateType", ""));
            String certificateNumber = String.valueOf(certificateData.getOrDefault("certificateNumber", ""));
            String issueDate = String.valueOf(certificateData.getOrDefault("issueDate", ""));
            String institution = String.valueOf(certificateData.getOrDefault("institution", ""));
            boolean isValid = Boolean.parseBoolean(String.valueOf(certificateData.getOrDefault("isValid", "true")));
            
            if (certificateType.isEmpty() || certificateNumber.isEmpty() || 
                issueDate.isEmpty() || institution.isEmpty()) {
                return CommonResponse.error("证书类型、编号、颁发日期和机构不能为空");
            }
            
            // 转换ID为数字
            BigInteger certId;
            try {
                certId = new BigInteger(certificateId);
                if (certId.compareTo(BigInteger.ZERO) <= 0) {
                    return CommonResponse.error("证书ID必须为正整数");
                }
            } catch (NumberFormatException e) {
                return CommonResponse.error("无效的证书ID格式: " + certificateId);
            }
            
            // 生成证书哈希 - 使用简单的哈希计算方法
            String dataToHash = certificateType + certificateNumber + issueDate + institution;
            byte[] hash = generateSimpleHash(dataToHash);
            
            // 找到对应的服务实例
            String serviceKey = serviceMap.keySet().iterator().next();
            EducationCertificationService service = serviceMap.get(serviceKey);
            
            if (service == null) {
                return CommonResponse.error("未找到合约服务实例");
            }
            
            // 构建更新证书的输入参数
            EducationCertificationUpdateCertificateInputBO inputBO = new EducationCertificationUpdateCertificateInputBO();
            inputBO.set_certificateId(certId);
            inputBO.set_certificateType(certificateType);
            inputBO.set_certificateNumber(certificateNumber);
            inputBO.set_issueDate(issueDate);
            inputBO.set_institution(institution);
            inputBO.set_hash(hash);
            inputBO.set_isValid(isValid);
            
            // 调用服务更新证书
            System.out.println("调用合约更新证书 - 输入参数: " + inputBO);
            TransactionResponse response = service.updateCertificate(inputBO);
            
            if (response == null) {
                return CommonResponse.error("交易响应为空");
            }
            
            if (response.getTransactionReceipt() == null) {
                return CommonResponse.error("交易回执为空");
            }
            
            // 构建返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("certificateId", certId.toString());
            result.put("certificateType", certificateType);
            result.put("certificateNumber", certificateNumber);
            result.put("issueDate", issueDate);
            result.put("institution", institution);
            result.put("isValid", isValid);
            result.put("txHash", response.getTransactionReceipt().getTransactionHash());
            result.put("blockNumber", response.getTransactionReceipt().getBlockNumber());
            result.put("status", "updated");
            
            return CommonResponse.ok(result);
        } catch (Exception e) {
            System.err.println("更新证书出错: " + e.getMessage());
            e.printStackTrace();
            return CommonResponse.error("更新证书失败: " + e.getMessage());
        }
    }

    // 简易的哈希生成方法 - 为了与合约中的哈希计算方式兼容
    private byte[] generateSimpleHash(String data) {
        // 生成32字节(256位)哈希
        byte[] hash = new byte[32];
        
        // 简单的哈希方式，仅用于演示
        byte[] dataBytes = data.getBytes();
        int dataLength = dataBytes.length;
        
        // 填充哈希数组
        for (int i = 0; i < 32; i++) {
            if (i < dataLength) {
                hash[i] = dataBytes[i];
            } else {
                // 如果数据长度不足32字节，使用0填充
                hash[i] = 0;
            }
        }
        
        return hash;
    }

    @GetMapping("/certificates/{certificateId}/verify")
    public CommonResponse<Boolean> verifyCertificate(
            @PathVariable String certificateId,
            @RequestParam(required = false) String hash,
            @RequestParam(required = false) String studentId,
            @RequestParam(required = false) String contractAddress,
            @RequestParam(required = false) Integer groupId) {
        try {
            System.out.println("\n============= 开始验证证书 =============");
            System.out.println("收到验证证书请求，证书ID: " + certificateId + ", 哈希: " + hash);
            
            if (certificateId == null || certificateId.isEmpty()) {
                System.err.println("证书ID为空");
                return CommonResponse.error("Certificate ID cannot be empty");
            }
            
            // 检查服务可用性
            if (serviceMap == null || serviceMap.isEmpty()) {
                System.err.println("区块链服务不可用");
                return CommonResponse.error("Blockchain service not available");
            }
            
            // 获取第一个可用的服务实例
            String serviceKey = serviceMap.keySet().iterator().next();
            EducationCertificationService service = serviceMap.get(serviceKey);
            
            if (service == null) {
                System.err.println("未找到合约服务实例");
                return CommonResponse.error("Blockchain service instance not available");
            }
            
            System.out.println("合约地址: " + service.getAddress());
            System.out.println("使用服务实例: " + serviceKey);
            
            try {
                // 验证证书ID能否转换为BigInteger
                BigInteger certId;
                try {
                    certId = new BigInteger(certificateId);
                    System.out.println("证书ID转换为BigInteger成功: " + certId);
                } catch (NumberFormatException e) {
                    System.err.println("证书ID格式错误，无法转换为数字: " + e.getMessage());
                    return CommonResponse.error("Invalid certificate ID format: " + e.getMessage());
                }
                
                // 获取证书哈希 - 从请求参数中获取或从区块链获取
                byte[] hashBytes;
                
                if (hash == null || hash.isEmpty()) {
                    System.out.println("请求中未提供哈希，尝试从区块链获取证书信息");
                    
                    // 首先尝试获取证书信息
                    EducationCertificationGetCertificateInputBO getCertInput = 
                        new EducationCertificationGetCertificateInputBO(certId);
                    
                    CallResponse certResponse = service.getCertificate(getCertInput);
                    
                    if (certResponse == null || certResponse.getValues() == null) {
                        System.err.println("从区块链获取证书信息失败");
                        return CommonResponse.error("Failed to get certificate info from blockchain");
                    }
                    
                    // 尝试从证书数据中获取哈希
                    try {
                        // 调用certificates映射获取原始证书数据（包含哈希）
                        EducationCertificationCertificatesInputBO certMapInput = 
                            new EducationCertificationCertificatesInputBO(certId);
                        
                        CallResponse certMapResponse = service.certificates(certMapInput);
                        
                        if (certMapResponse != null && certMapResponse.getValues() != null) {
                            String certDataStr = cleanBlockchainResponse(certMapResponse.getValues());
                            System.out.println("证书原始数据: " + certDataStr);
                            
                            // 尝试提取哈希 - 通常是第6个字段
                            String[] certFields = certDataStr.split(",");
                            if (certFields.length >= 6) {
                                String hashHex = certFields[5].trim();
                                // 如果有0x前缀，去掉
                                if (hashHex.startsWith("0x")) {
                                    hashHex = hashHex.substring(2);
                                }
                                
                                System.out.println("从证书数据中提取哈希: " + hashHex);
                                hashBytes = org.fisco.bcos.sdk.utils.Numeric.hexStringToByteArray(hashHex);
                            } else {
                                // 如果无法从证书数据中提取哈希，生成一个临时哈希
                                System.err.println("无法从证书数据中提取哈希，使用默认哈希");
                                hashBytes = new byte[32]; // 32字节的空哈希
                            }
                        } else {
                            System.err.println("无法获取证书原始数据，使用默认哈希");
                            hashBytes = new byte[32]; // 32字节的空哈希
                        }
                    } catch (Exception e) {
                        System.err.println("从区块链获取证书哈希失败: " + e.getMessage());
                        return CommonResponse.error("Failed to get certificate hash: " + e.getMessage());
                    }
                } else {
                    // 使用请求中提供的哈希
                    System.out.println("使用请求中提供的哈希: " + hash);
                    
                    // 将哈希字符串转换为字节数组
                    try {
                        // 确保哈希有正确的格式（0x前缀）
                        String hashHex = hash;
                        if (!hashHex.startsWith("0x")) {
                            hashHex = "0x" + hashHex;
                        }
                        
                        // 转换为字节数组
                        hashBytes = org.fisco.bcos.sdk.utils.Numeric.hexStringToByteArray(hashHex);
                        
                        // 确保哈希长度为32字节
                        if (hashBytes.length != 32) {
                            byte[] paddedHash = new byte[32];
                            System.arraycopy(hashBytes, 0, paddedHash, 0, Math.min(hashBytes.length, 32));
                            hashBytes = paddedHash;
                        }
                    } catch (Exception e) {
                        System.err.println("哈希格式错误，无法转换为字节数组: " + e.getMessage());
                        return CommonResponse.error("Invalid hash format: " + e.getMessage());
                    }
                }
                
                // 组装输入参数，直接调用智能合约验证证书
                EducationCertificationVerifyCertificateInputBO inputBO = 
                    new EducationCertificationVerifyCertificateInputBO();
                inputBO.set_certificateId(certId);
                inputBO.set_hash(hashBytes);
                
                System.out.println("准备调用智能合约验证证书");
                System.out.println("证书ID: " + certId);
                System.out.println("证书哈希: " + org.fisco.bcos.sdk.utils.Numeric.toHexString(hashBytes));
                
            CallResponse response = service.verifyCertificate(inputBO);
                
                if (response == null) {
                    System.err.println("验证证书响应为空");
                    return CommonResponse.error("Verification response is null");
                }
                
                if (response.getValues() == null) {
                    System.err.println("验证证书结果为空");
                    return CommonResponse.error("Verification result is null");
                }
                
                // 清理并解析响应
                String verifyResult = cleanBlockchainResponse(response.getValues());
                System.out.println("验证证书原始响应: " + response.getValues());
                System.out.println("验证证书清理后响应: " + verifyResult);
                
                // 解析验证结果
                boolean verified = "true".equalsIgnoreCase(verifyResult) || 
                                   "1".equals(verifyResult);
                
                System.out.println("证书验证结果: " + (verified ? "有效" : "无效"));
                System.out.println("============= 验证证书完成 =============\n");
                return CommonResponse.ok(verified);
            } catch (Exception e) {
                System.err.println("验证证书过程中出错: " + e.getMessage());
                e.printStackTrace();
                return CommonResponse.error("Failed to verify certificate: " + e.getMessage());
            }
        } catch (Exception e) {
            System.err.println("验证证书请求处理失败: " + e.getMessage());
            e.printStackTrace();
            return CommonResponse.error("Failed to process certificate verification: " + e.getMessage());
        }
    }
}